#!/usr/bin/python
#! encoding:utf8

import logging
import os
import re
import shutil
import tempfile
import xml.etree.ElementTree as ET
import zipfile
from functools import partial
from sys import version_info

python_major = tuple(version_info)[0]

if python_major >=3:
    XMLTreeBuilder = ET.TreeBuilder
    class CommentedTreeBuilder(XMLTreeBuilder):
        """A TreeBuilder subclass that retains comments."""

        def comment(self, data):
            self.start(ET.Comment, {})
            self.data(data)
            self.end(ET.Comment)

    parser = ET.XMLParser(target = CommentedTreeBuilder())
else:
    XMLTreeBuilder = ET.XMLTreeBuilder
    class PCParser(XMLTreeBuilder):
        
        def __init__(self):
            XMLTreeBuilder.__init__(self)
            # assumes ElementTree 1.2.X
            self._parser.CommentHandler = self.handle_comment
            
        def handle_comment(self, data):
            self._target.start(ET.Comment, {})
            self._target.data(data)
            self._target.end(ET.Comment)
    parser = PCParser()

def log(message):
    logging.basicConfig(format='%(levelname)s:\t%(message)s', level=logging.DEBUG)
    logging.info(message)


def _replace_value(xmlobj, locate, replace_to, namespaces):
    root = xmlobj
    node = root.find(locate, namespaces)
    if node is not None:
        log('find noe: {}'.format(node.tag))
        if replace_to[1] == '':
            node.text = replace_to[0]
        else:
            node.set(replace_to[1], replace_to[0])
    else:
        log('not match {}'.format(locate))
    return root


def replace_xml_str_value(xmlstr, locate, replace_to, namespaces={}):
    if namespaces:
        for prefix, uri in namespaces.items():
            ET.register_namespace(prefix, uri)

    root = ET.fromstring(xmlstr, parser)
    _replace_value(root, locate, replace_to, namespaces)


def replace_xml_file_value(path, locate, replace_to, namespaces={}):
    temp_path = remov_default_namespace(path)
    if namespaces:
        for prefix, uri in namespaces.items():
            ET.register_namespace(prefix, uri)

    tree = ET.parse(temp_path, parser=parser )
    root = tree.getroot()

    r_root = _replace_value(root, locate, replace_to, namespaces)
    root.set('xmlns', namespaces.get('default'))
    log('write to {}'.format('xxx.xml'))
    tree.write('xxx.xml')


def get_default_namespace(xmlpath):
    with open(xmlpath) as f:
        xmlstring = f.read()
    xmlstring = re.sub(r'\sxmlns="[^"]+"', '', xmlstring, count=1)


def remov_default_namespace(xmlpath):
    xmlpath = shutil.copy(xmlpath,tempfile.gettempdir())
    with open(xmlpath) as f:
        xmlstring = f.read()
    # Remove the default namespace definition (xmlns="http://some/namespace")
    with open(xmlpath, 'w') as w:
        xmlstring = re.sub(r'\sxmlns="[^"]+"', '', xmlstring, count=1)
        w.write(xmlstring)
    return xmlpath


def test_replace_xml_file_value(*arg, **args):
    path = args.get('path')
    namespaces = args.get('namespaces')
    log(args)
    for value in args.get('values'):
        locate = value.get('locate')
        replace_to = value.get('replace_to')
        replace_xml_file_value(path, locate, replace_to, namespaces)
        path = 'xxx.xml'


pattern = {
    'Proxy_web_xml' : dict(
        path = 'pip_proxy_web.xml',
        namespaces = {
            'default': "http://java.sun.com/xml/ns/javaee",
        },
        values = [
            dict(locate = "servlet/init-param/param-value",
                 replace_to = 'http://10.119.67.11111:9002',),
        ]
    ),

    'deployerConfigContext' : dict(
        path = 'GC/deployerConfigContext.xml',
        namespaces = dict(
            default="http://www.springframework.org/schema/beans",
            xsi="http://www.w3.org/2001/XMLSchema-instance",
            p="http://www.springframework.org/schema/p",
            tx="http://www.springframework.org/schema/tx",
            sec="http://www.springframework.org/schema/security",
        ),
        values = [
            dict(locate = "bean[@id='dataSource_staticdb']/property[@name='url']",
                 replace_to = ("jdbc:oracle:thin:@192.168.240.111117:1521:HWGCDB", 'value'),
            ),
            dict(locate = "bean[@id='dataSource_staticdb']/property[@name='username']",
                 replace_to = ('usernametest', ''),
            ),
            dict(locate = "bean[@id='dataSource_staticdb']/property[@name='password']",
                 replace_to = ('passwordtest',''),
            ),

        ],
    ),
}


if '__main__' == __name__:
    log(pattern)
    # test_replace_xml_file_value(pattern.get('Proxy_web_xml'))
    test_replace_xml_file_value(**pattern.get('deployerConfigContext'))
